package com.twinkle.dbmanage.ui;

import javax.swing.table.AbstractTableModel;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @param <T>
 * @author Twinkle
 */
public class SelfTableModel<T> extends AbstractTableModel {
    private List<T> dataList;
    private String[] header;
    private Map<Integer, String> columnOrder;

    public SelfTableModel() {

    }

    public SelfTableModel(List<T> dataList, String[] header) {
        this.dataList = dataList;
        this.header = header;
        columnOrder = new HashMap<>();
    }

    public Map<Integer, String> getColumnOrder() {
        return columnOrder;
    }

    public void setColumnOrder(Integer columnIndex, String fieldName) {
        columnOrder.put(columnIndex, fieldName);
    }

    public List<T> getDataList() {
        return dataList;
    }

    public void setDataList(List<T> dataList) {
        this.dataList = dataList;
    }

    public String[] getHeader() {
        return header;
    }

    public void setHeader(String[] header) {
        this.header = header;
    }

    @Override
    public String getColumnName(int column) {
        return header[column];
    }

    @Override
    public int getRowCount() {
        return dataList.size();
    }

    @Override
    public int getColumnCount() {
        return header.length;
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        T t = dataList.get(rowIndex);
        if (t instanceof Object[]) {
            Object[] data = (Object[]) t;
            return data[columnIndex];
        } else {
            String fieldName = columnOrder.get(columnIndex);
            return getFieldVal(t, fieldName);
        }
    }

    private Object getFieldVal(T t, String fieldName) {
        Class<?> cls = t.getClass();
        String methodName = "get" + Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1);
        Method method = null;
        try {
            method = cls.getDeclaredMethod(methodName, new Class[]{});
            Object obj = method.invoke(t, new Object[]{});
            if (obj instanceof Date) {
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
                return simpleDateFormat.format((Date) obj);
            }
            return obj;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
